org.dreamwork.js.util.Calendar2 = function () {
	var time= arguments [0] ? arguments [0] : new Date ();
	var today = new Date ();
	var panel, mask;
	var locale = org.dreamwork.js.util.Util.locale.toUpperCase () || "DEFAULT";
	var body = null, header = null, footer = null;
	var self = this;
	var Titles = {
          year: {"ZH-CN":{prev:"上一年",next:"下一年"},"DEFAULT":{prev: "Previous Year", next: "Next Year"}},
         month: {"ZH-CN":{prev:"上个月",next:"下个月"},"DEFAULT":{prev: "Previous Month", next: "Next Month"}},
        button: {"ZH-CN":"取消", "DEFAULT":"Cancel"},
         clear: {"ZH-CN":"清除", "DEFAULT":"Clear"},
   today_title: {"ZH-CN":"今天","DEFAULT":"Today"}
    };
    var f = [Date.HOUR, Date.MINUTE, Date.SECOND];
	var parent;

	this.date = today, this.today = today;
	// events
	var on_close_events = [];
    on_close_events.push (function () {
        if (!parent) return;
        var tagName = parent.tagName.toUpperCase ();
        var value = self.date.format();
        if (parent && parent.showTime)
            value += (parent.showTime ? " " + document.getElementById ('calendar-input').value : "");
        if (tagName == "INPUT" || tagName == "TEXTAREA") parent.value = value;
        else parent.innerHTML = value;

        if (parent.showTime) {
            var part = document.getElementById ('calendar-input').value;
            var a = part.split (':');
            for (var i = 0; i < a.length; i ++) {
                self.date.set (f [i], parseInt (a[i], 10));
            }
        }
    });

	// public method
	this.close = function(){
        var e = {calendar: self, target: parent};
        for (var i = 0; i < on_close_events.length; i ++) on_close_events [i] (e);
        panel.style.display = "none";
        if (mask) mask.style.display = 'none'
    };
	this.cancel = function () {
        panel.style.display = "none";
        if (mask) mask.style.display = 'none';
    };

	this.install = function (element, flag) {
		if (typeof element == "string") element = document.getElementById (element);
		element.showTime = flag;
		element.onclick = function () {
			parent = element;
			var text = "";
			var tagName = element.tagName.toUpperCase ();
			if (tagName == "INPUT" || tagName == "TEXTAREA") text = element.value;
			else text = element.innerHTML;
			if (Date.isDateString (text)) time = Date.parseDate (text);
			else if (Date.isTimeString (text)) time = Date.parseTime (text);
			else time = new Date ();
			if (element.showTime) {
				var c = document.getElementById ("calendar-input");
				if (c) c.value = time.getTimePart ();
			}
			getPosition (element);
		};
	};

	this.shown = function () {
		header.style.width = body.clientWidth;
		footer.style.width = body.clientWidth;
		panel.style.width = body.clientWidth;
		panel.style.height = header.scrollHeight + footer.scrollHeight + body.scrollHeight;

		var height = panel.scrollHeight;
		var pos = {x:parseInt (panel.style.left), y:parseInt (panel.style.top)};
		if (pos.y + height >= document.body.clientHeight) {
			pos.y -= height;
			panel.style.top = pos.y + "px";
		}
	};

	this.addOnCloseEvent = function (event) { on_close_events.push (event); };
	this.setTime = function (date) { if (date instanceof Date) time.copy (date); };
	this.getPanel = function () { return panel; };
	this.callback = function () {};

	// private method
	function getPosition (element) {
		if (!panel) buildPanel ();
		buildDateGrid (body);
		
		if (parent && parent.showTime) {
			document.getElementById ("calendar-timer").style.display = "block";
		} else {
			document.getElementById ("calendar-timer").style.display = "none";
		}

		var pos = org.dreamwork.js.util.Util.getPosition (element);
		var clientHeight = element.offsetHeight;
		pos.y += clientHeight;

		panel.style.display = "block";
		panel.style.left = pos.x + "px";
		panel.style.top = pos.y + "px";

        var height = panel.scrollHeight;
        var HEIGHT = window.outerHeight;
        var scrollY = window.scrollY || window.pageYOffset;
        var upper = pos.y - scrollY;
        var bottom = HEIGHT - upper;

        if (bottom < height && upper > height) {
            pos.y -= clientHeight;
            pos.y -= height;
            panel.style.top = pos.y + "px";
        }

        var ie6 = window.navigator.userAgent.indexOf("MSIE 6") >= 0;
        if (ie6) {
            var x = parseInt (panel.style.left);
            var y = parseInt (panel.style.top);
            var w = panel.clientWidth;
            var h = panel.clientHeight;
            patchIE6 (x, y, w, h);
        }
	}

    function patchIE6 (x, y, w, h) {
        if (!mask) {
            mask = document.createElement("iframe");
            mask.id = "_$_calendar_msak_$_";
            mask.style.position = 'absolute';
            mask.style.border = 'none';
            mask.style.backgroundColor = '#f00';
            mask.style.zIndex = 99;
            document.body.appendChild(mask);
        }
        mask.style.display = 'block';
        mask.style.left = x + 'px';
        mask.style.top = y + 'px';
        mask.style.width = w + 'px';
        mask.style.height = h + 'px';
    }

	function buildPanel () {
		panel = document.createElement ("div");
		panel.id = "calendar-panel";
        panel.style.zIndex = 500;
		document.body.appendChild (panel);
		createControlPanel ();
		panel.appendChild (createHeader ());
		buildBody ();
		panel.appendChild (body);
		buildTimer ();
	}

	function createHeader () {
		var header = document.createElement ("div");
		header.id = "calendar-header";
		createSubElement (header, "«", "left", Date.YEAR, -1);
		createSubElement (header, "‹", "left", Date.MONTH, -1);
		createSubElement (header, "»", "right", Date.YEAR, 1);
		createSubElement (header, "›", "right", Date.MONTH, 1);
		var month = document.createElement ("div");
		month.id = "calendar-title";
		header.appendChild (month);
		var clear = document.createElement ("div");
		clear.style.clear = "both";
		header.appendChild (clear);
		return header;
	}

	function createControlPanel () {
		var c = document.createElement ("div");
		c.id = "calendar-control";
		panel.appendChild (c);

		var close = document.createElement ("div");
		close.className = "right";
		close.innerHTML = Titles.button[locale] || Titles.button ['DEFAULT'];
		close.onclick = function () { self.cancel();};
		c.appendChild (close);

		var clear = document.createElement ("div");
		clear.className = "right";
		clear.innerHTML = Titles.clear[locale] || Titles.clear ['DEFAULT'];
		clear.onclick = function () {
			if (!parent) return;
			var tagName = parent.tagName.toUpperCase ();
			if (tagName == "INPUT" || tagName == "TEXTAREA") parent.value = "";
			else parent.innerHTML = "";
            self.cancel();
		};
		c.appendChild (clear);

		var empty = document.createElement ("div");
		empty.className = "clear";
		c.appendChild (empty);
	}

	function createSubElement (header, innerHTML, className, field, offset) {
		var e = document.createElement ("div");
		e.className = className;
		e.innerHTML = innerHTML;
		e.onclick = function () {
			time.add (field, offset);
			buildDateGrid (body);
		};
		header.appendChild (e);
	}


	function buildBody () {
		if (!body) {
			body = document.createElement ("table");
			body.cellPadding=0;
			body.cellSpacing=0;
		} else {
			body.innerHTML = "";
		}
		var title = body.insertRow (-1);
		var week_space = title.insertCell (-1);
		week_space.innerHTML = Date.Week [locale] || Date.Week ['DEFAULT'];
		week_space.className = "calendar-week";
		for (var i = 1; i <= 7; i ++) {
			var cell = document.createElement ("th");
			title.appendChild (cell);
            var WeekTitles = Date.WeekTitles [locale] || Date.WeekTitles ['DEFAULT'];
			cell.innerHTML = WeekTitles [i - 1];
			if (i == 1 || i == 7) cell.className = "calendar-weekend";
		}
		return body;
	}
	
	function clearDateGrid () {while (body.rows.length > 1) body.deleteRow (1);}
	function buildDateGrid (body) {
		clearDateGrid ();
		var date = new Date (time.getFullYear (), time.getMonth (), time.getDate ());
		if (arguments [1]) date.setMonth (arguments [1]);
		var month = date.getMonth ();

		var title = document.getElementById ("calendar-title");
		if (title) {
            var MonthTitles = Date.MonthTitles[locale] || Date.MonthTitles ['DEFAULT'];
			title.innerHTML = time.getFullYear () + "年" + MonthTitles [time.getMonth ()];
        }
		date.setDate (1);
		var week = date.getWeekOfYear ();
		var weeks = date.getWeeksInMonth ();
		date.add (Date.DAY_OF_MONTH, -date.getDay ());
		for (var i = 0; i < weeks; i ++) {
			var tr = body.insertRow (-1);
			var week_space = tr.insertCell (-1);
			week_space.innerHTML = week + i;
			week_space.className = "calendar-week";

			for (var j = 0; j < 7; j ++) {
				var cell = tr.insertCell (-1);
				cell.innerHTML = date.getDate ();
				if (date.getMonth() != month) 
					cell.className="calendar-not-current-month";
				else {
					if (j == 0 || j == 6) cell.className = "calendar-weekend";
					if (date.format () == time.format ()) cell.className = "selected-cell";
					if (date.format () == today.format()) cell.className = "today";
				}

				cell.onclick = function (event) { 
					if (!event) event = window.event;
					if (!event.target) event.target = event.srcElement;
					self.date = event.target.date;
					self.close ();
				};
				cell.title = date.format ();
				cell.date = new Date (date.getFullYear(), date.getMonth (), date.getDate ());
				date.add (Date.DAY_OF_MONTH, 1);
			}
		}
	}

	function buildTimer () {
		var timer = document.createElement ("div");
		timer.id = "calendar-timer";
		timer.innerHTML = "请输入时间(HH:MM:SS):";
		var input = document.createElement ("input");
		input.id = "calendar-input";
		input.size = 8;
		input.maxLength = 8;
		input.value = time.getTimePart ();
		input.onchange = function () {
			var reg = /^(([01]?[0-9])|(2[0-3])):([0-5]?[0-9]):([0-5]?[0-9])$/;
			var c = document.getElementById ("calendar-input");
			if (!reg.test (c.value)) {
				alert ("时间格式有误");
			}
		};
		input.onkeyup = function () {
			var c = document.getElementById ("calendar-input");
			var reg2 = /[0-9:]/;
			if (c && c.value && c.value.length > 0) {
				var ch = c.value.charAt (c.value.length - 1);
				if (!reg2.test (ch)) {
					if (c.value.length == 1) c.value = "";
					else c.value = c.value.substring (0, c.value.length - 1);
				}
			}
		};
		timer.appendChild (input);
		panel.appendChild (timer);
	}
};